home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / polyview / polyvw31.lha / Polyview3.1 / new / pvraster.c < prev    next >
C/C++ Source or Header  |  1993-08-24  |  14KB  |  447 lines

  1. /*****************************************************************************
  2.  * NCSA Polyview 3.1                                                         *
  3.  *                                                                           *
  4.  * Version 3.1 changes and additions by Gilles Bourhis.                      *
  5.  * Version 3 changes and additions by Marc Andreessen.                       *
  6.  * Version 2 by Brian Calvert.                                               *
  7.  *                                                                           *
  8.  * Software Development Group                                                *
  9.  * National Center for Supercomputing Applications                           *
  10.  * University of Illinois at Urbana-Champaign                                *
  11.  *                                                                           *
  12.  * This is BETA release software.  As such it may contain software bugs and  *
  13.  * exhibit inconsistencies.                                                  *
  14.  *                                                                           *
  15.  * Please send bug reports to polyview@ncsa.uiuc.edu.                        *
  16.  *                                                                           *
  17.  * Copyright (c) 1992 The Board of Trustees of the University of Illinois.   *
  18.  *                                                                           *
  19.  * Permission to use, copy, and modify this software and its                 *
  20.  * documentation for educational, research, and non-profit purposes is       *
  21.  * hereby granted, provided that the above copyright notice, the original    *
  22.  * authors names, and this permission notice appear in all such copies.      *
  23.  * Any distribution of this software requires the explicit and written       *
  24.  * authorization of the authors.                                             *
  25.  *                                                                           *
  26.  * The University of Illinois makes no representations about the             *
  27.  * suitability of this software for any purpose.  It is provided "as is"     *
  28.  * without warranty of any kind.                                             *
  29.  *****************************************************************************/
  30.  
  31. /* $Id: pvraster.c,v 1.3 93/08/24 10:27:43 gbourhis Exp $ */
  32.  
  33. #ifdef RCSLOG
  34. $Log:    pvraster.c,v $
  35.  * Revision 1.3  93/08/24  10:27:43  gbourhis
  36.  * replace version string from 3.0 to 3.1
  37.  * 
  38.  * Revision 1.2  93/06/24  16:34:16  gbourhis
  39.  * add some casting to parameter of HDF routines.
  40.  * 
  41.  * Revision 1.1  92/09/18  10:55:26  marca
  42.  * Initial revision
  43.  * 
  44. #endif
  45.  
  46. #include "pv.h"
  47. #include "net.h"
  48.  
  49. #define QUANT_SUPPORT
  50.  
  51. #ifdef QUANT_SUPPORT
  52. extern unsigned char *Ir, *Ig, *Ib;
  53. extern int quant_size;
  54. extern int K;
  55. extern short int *Qadd;
  56. extern unsigned char lut_r[256], lut_g[256], lut_b[256];
  57. extern int doquant();
  58. #endif
  59.  
  60. extern int NetSendRaster8Group 
  61.   (NetPort *, char *, unsigned char *, int, int, unsigned char *, int,
  62.    int, char *);
  63.  
  64. int WriteRaster(state_t *state, window_t *win, char *outfile)
  65. {
  66.   unsigned long *sgiimage;
  67.   unsigned char *hdfimage;
  68.   static unsigned char palette[768];
  69.   int i, j;
  70.   int width, height;
  71.   int rv;
  72.   static Matrix m;
  73.   char base[MAXPATHLEN];
  74.   char full[MAXPATHLEN];
  75.   polyview_t *pv;
  76.   
  77.   if (win->type != POLYVIEW)
  78.     return ST_ERROR;
  79.   
  80.   /* Set up initial data structures. */
  81.   width = WIN_WIDTH(win) - 2;
  82.   height = WIN_HEIGHT(win) - 2;
  83.   sgiimage = (unsigned long *)malloc (width * height * sizeof (unsigned long));
  84.   hdfimage = (unsigned char *)malloc (width * height * sizeof (unsigned char));
  85.   
  86.   /* Generate the filename and update count. */
  87.   strsub(base, WIN_RASTERNAME(win), ".hdf", "");
  88.   sprintf(full, "%s%04d.hdf", base, WIN_RASTERNUM(win));
  89.   WIN_RASTERNUM(win)++;
  90.   
  91.   /* Tell the user that the grab is beginning. */
  92.   stprintf(state, "Reading %s image...", WIN_NAME(win));
  93.   
  94.   /* Focus on the right window. */
  95.   pv = (polyview_t *)WIN_IMAGE(win);
  96.   XmxWinset (pv->drawing_volume);
  97.   
  98.   /* Save the projection matrix. */
  99.   mmode (MPROJECTION);
  100.   getmatrix (m);
  101.   mmode (MVIEWING);
  102.   
  103.   /* Save the viewport. */
  104.   pushviewport ();
  105.   
  106.   /* Read the image; screenspace loads the viewport and does
  107.      an ortho2, which loads the projection matrix in MVIEWING mode. */
  108.   readsource (SRC_FRONT);
  109.   screenspace ();
  110.   lrectread (1, 1, width, height, sgiimage);
  111.   
  112.   /* Restore the projection matrix. */
  113.   mmode (MPROJECTION);
  114.   loadmatrix (m);
  115.   mmode (MVIEWING);
  116.   
  117.   /* Restore the viewport. */
  118.   popviewport ();
  119.   
  120.   /* With QUANT_SUPPORT enabled, the quantization algorithm by Wu */
  121. #ifdef QUANT_SUPPORT
  122.   Ir = (unsigned char *)malloc (width * height * sizeof (unsigned char));
  123.   Ig = (unsigned char *)malloc (width * height * sizeof (unsigned char));
  124.   Ib = (unsigned char *)malloc (width * height * sizeof (unsigned char));
  125.   for (j = 0; j < height; j++)
  126.     for (i = 0; i < width; i++)
  127.       {
  128.         Ir[(height-j-1)*width+i] = 
  129.           (sgiimage[j*width+i] & 0x000000ff);
  130.         Ig[(height-j-1)*width+i] = 
  131.           (sgiimage[j*width+i] & 0x0000ff00) >> 8;
  132.         Ib[(height-j-1)*width+i] = 
  133.           (sgiimage[j*width+i] & 0x00ff0000) >> 16;
  134.       }
  135.   
  136.   quant_size = width * height;
  137.   K = 200;
  138.   
  139.   doquant ();
  140.   /* Ir/Ig/Ib freed in doquant */
  141.   
  142.   /* Now lut_r, lut_g, lut_b are LUT contents,
  143.      and Qadd is the quantized image. */
  144.   for (i = 0; i < (width * height); i++)
  145.     hdfimage[i] = Qadd[i];
  146.   
  147.   free (Qadd);
  148.   
  149.   for (i = 0; i < 256; i++)
  150.     {
  151.       palette[i*3+0] = lut_r[i];
  152.       palette[i*3+1] = lut_g[i];
  153.       palette[i*3+2] = lut_b[i];
  154.     }
  155. #else /* not QUANT_SUPPORT */
  156.   /* Convert to hdf colorindex format.  We want 3-3-2 dithering. */
  157.   for (j = 0; j < height; j++)
  158.     for (i = 0; i < width; i++)
  159.         hdfimage[(height-j-1)*width+i] = 
  160.           (
  161.            (((sgiimage[j*width+i] & 0x000000ff) >> (8 - 3))) |
  162.            (((sgiimage[j*width+i] & 0x0000ff00) >> (8 + 8 - 3)) << 3) |
  163.            (((sgiimage[j*width+i] & 0x00ff0000) >> (16 + 8 - 2)) << 6)
  164.            );
  165.   
  166.   /* Construct 3-3-2 RGB palette. */
  167.   for (i = 0; i < 256; i++)
  168.     {
  169.       /* Red value is low-order three bits = 1 + 2 + 4,
  170.          shifted into upper three bits. */
  171.       palette[i*3+0] = ((unsigned char)i & (unsigned char)7) << 5;
  172.       /* Green value is middle three bits = 8 + 16 + 32,
  173.          shifted into upper three bits. */
  174.       palette[i*3+1] = ((unsigned char)i & (unsigned char)56) << 2;
  175.       /* Blue value is upper two bits = 64 + 128,
  176.          shifted into upper two bits. */
  177.       palette[i*3+2] = ((unsigned char)i & (unsigned char)192);
  178.     }
  179. #endif /* not QUANT_SUPPORT */
  180.   
  181.   /* Tell the user that the image is being written. */
  182.   stprintf(state, "Writing %s image to '%s'...", WIN_NAME(win), full);
  183.   
  184.   /* Set the palette for the file. */
  185.   DFR8setpalette(palette);
  186.   
  187.   /* Write the image to the file. */
  188.   DFR8putimage(full, (char *)hdfimage, width, height, DFTAG_RLE);
  189.   
  190.   /* Tell the user that the image is being written. */
  191.   stprintf(state, "Image write complete...");
  192.   
  193.   /* Free the memory buffers. */
  194.   free (hdfimage);
  195.   free (sgiimage);
  196.   
  197.   return ST_OKAY;
  198. }
  199.  
  200.  
  201. /* Make sure we don't super-quantize DTM stuff. */
  202. #undef QUANT_SUPPORT
  203.  
  204. /* This is the new WriteRaster which writes via a DTM outport
  205.    rather than to a file.  This should be renamed COMsendRaster
  206.    or something similar. */
  207. int WriteRasterOverDTM (state_t *state, window_t *win)
  208. {
  209.   unsigned long *sgiimage;
  210.   unsigned char *hdfimage;
  211.   static unsigned char palette[768];
  212.   int i, j;
  213.   int width, height;
  214.   int rv;
  215.   static Matrix m;
  216.   polyview_t *pv;
  217.   
  218.   if (win->type != POLYVIEW)
  219.     return ST_ERROR;
  220.   
  221.   /* Set up initial data structures. */
  222.   width = WIN_WIDTH(win);
  223.   height = WIN_HEIGHT(win);
  224.   sgiimage = (unsigned long *)malloc (width * height * sizeof (unsigned long));
  225.   hdfimage = (unsigned char *)malloc (width * height * sizeof (unsigned char));
  226.   
  227.   /* Focus on the right window. */
  228.   pv = (polyview_t *)WIN_IMAGE(win);
  229.   XmxWinset (pv->drawing_volume);
  230.   
  231.   /* Save the projection matrix. */
  232.   mmode (MPROJECTION);
  233.   getmatrix (m);
  234.   mmode (MVIEWING);
  235.   
  236.   /* Save the viewport. */
  237.   pushviewport ();
  238.   
  239.   /* Read the image; screenspace loads the viewport and does
  240.      an ortho2, which loads the projection matrix in MVIEWING mode. */
  241.   readsource (SRC_FRONT);
  242.   screenspace ();
  243.   lrectread (0, 0, width - 1, height - 1, sgiimage);
  244.   
  245.   /* Restore the projection matrix. */
  246.   mmode (MPROJECTION);
  247.   loadmatrix (m);
  248.   mmode (MVIEWING);
  249.   
  250.   /* Restore the viewport. */
  251.   popviewport ();
  252.   
  253. #ifdef QUANT_SUPPORT
  254.   Ir = (unsigned char *)malloc (width * height * sizeof (unsigned char));
  255.   Ig = (unsigned char *)malloc (width * height * sizeof (unsigned char));
  256.   Ib = (unsigned char *)malloc (width * height * sizeof (unsigned char));
  257.   for (j = 0; j < height; j++)
  258.     for (i = 0; i < width; i++)
  259.       {
  260.         Ir[(height-j-1)*width+i] = 
  261.           (sgiimage[j*width+i] & 0x000000ff);
  262.         Ig[(height-j-1)*width+i] = 
  263.           (sgiimage[j*width+i] & 0x0000ff00) >> 8;
  264.         Ib[(height-j-1)*width+i] = 
  265.           (sgiimage[j*width+i] & 0x00ff0000) >> 16;
  266.       }
  267.   
  268.   quant_size = width * height;
  269.   K = 200;
  270.   
  271.   doquant ();
  272.   /* Ir/Ig/Ib freed in doquant */
  273.   
  274.   /* Now lut_r, lut_g, lut_b are LUT contents,
  275.      and Qadd is the quantized image. */
  276.   for (i = 0; i < (width * height); i++)
  277.     hdfimage[i] = Qadd[i] + 32;
  278.   
  279.   free (Qadd);
  280.   
  281.   for (i = 0; i < 200; i++)
  282.     {
  283.       palette[(i+32)*3+0] = lut_r[i];
  284.       palette[(i+32)*3+1] = lut_g[i];
  285.       palette[(i+32)*3+2] = lut_b[i];
  286.     }
  287. #else /* not QUANT_SUPPORT */
  288.   /* Convert to hdf colorindex format.  We want 3-3-2 dithering. */
  289.   for (j = 0; j < height; j++)
  290.     for (i = 0; i < width; i++)
  291.         hdfimage[(height-j-1)*width+i] = 
  292.           (
  293.            (((sgiimage[j*width+i] & 0x000000ff) >> (8 - 3))) |
  294.            (((sgiimage[j*width+i] & 0x0000ff00) >> (8 + 8 - 3)) << 3) |
  295.            (((sgiimage[j*width+i] & 0x00ff0000) >> (16 + 8 - 2)) << 6)
  296.            );
  297.   
  298.   /* Construct 3-3-2 RGB palette. */
  299.   for (i = 0; i < 256; i++)
  300.     {
  301.       /* Red value is low-order three bits = 1 + 2 + 4,
  302.          shifted into upper three bits. */
  303.       palette[i*3+0] = ((unsigned char)i & (unsigned char)7) << 5;
  304.       /* Green value is middle three bits = 8 + 16 + 32,
  305.          shifted into upper three bits. */
  306.       palette[i*3+1] = ((unsigned char)i & (unsigned char)56) << 2;
  307.       /* Blue value is upper two bits = 64 + 128,
  308.          shifted into upper two bits. */
  309.       palette[i*3+2] = ((unsigned char)i & (unsigned char)192);
  310.     }
  311. #endif /* not QUANT_SUPPORT */
  312.   
  313.   /* Blast across the network. */
  314.   /* outport can be NULL here; the net module will send the
  315.      message to all output ports. */
  316.   rv = NetSendRaster8Group 
  317.     (NULL, "Polyview 3.1 Image", hdfimage, width, height, palette, TRUE,
  318.      FALSE, NULL);
  319.   
  320.   /* Announce results in the status window. */
  321.   if (rv == -1)
  322.     stprintf (state, "ERROR broadcasting raster image.");
  323.   else
  324.     /* Dave says rv == 0 is also okay. */
  325.     stprintf (state, "Raster image transmission successful.");
  326.   
  327.   free (sgiimage);
  328.   free (hdfimage);
  329.   
  330.   return ST_OKAY;
  331. }
  332.  
  333.  
  334.  
  335. int ReadHDFPalette(state_t *state, window_t *win, char *infile)
  336. {
  337.   short    *polypalette;
  338.   unsigned char    palette[768];
  339.   int i;
  340.     
  341.   /* Read the palette from the file. */
  342.   if (DFPgetpal(infile, (char *)palette) == -1) 
  343.     {
  344.       stprintf(state, "ERROR:  Problem reading palette from '%s'.\n", infile);
  345.       return ST_ERROR;
  346.     }
  347.   
  348.   /* Convert the palette to PolyView format. */
  349.   for (polypalette = (short *) WIN_PALETTE(win)->master_palette, i = 0;
  350.        i < 768; i++, polypalette++)
  351.     *polypalette = (short) palette[i];
  352.   
  353.   DFPrestart();
  354.   cm_reset(state, win);
  355.   
  356.   return ST_OKAY;
  357. }
  358.  
  359.  
  360. int ReadRawPalette(state_t *state, window_t *win, char *infile)
  361. {
  362.   int i;
  363.   char red[256], blue[256], green[256];   /* character arrays that */
  364.                     /* contain palette rgb values */
  365.   FILE *fp; /* palette file to be used */
  366.     
  367.   if ((fp = fopen(infile, "r")) != NULL) 
  368.     {
  369.       /* Read in the raw palette from palette file */
  370.       fread(red,1,256,fp);
  371.       fread(green,1,256,fp);
  372.       fread(blue,1,256,fp);
  373.       fclose(fp);
  374.       
  375.       /* Copy colors into palette array for display */
  376.       for (i = 0; i < 256; i++) {
  377.         WIN_PALETTE(win)->master_palette[i][R] =(short)red[i];
  378.         WIN_PALETTE(win)->master_palette[i][G] =(short)green[i];
  379.         WIN_PALETTE(win)->master_palette[i][B] =(short)blue[i];
  380.       }
  381.     }
  382.   else 
  383.     {
  384.       stprintf(state, "ERROR:  Problem reading palette from '%s'.\n", infile);
  385.       return ST_ERROR;
  386.     }
  387.   
  388.   cm_reset(state, win);
  389.   
  390.   return ST_OKAY;
  391. }
  392.  
  393.  
  394. int WriteHDFPalette(state_t *state, window_t *win, char *outfile)
  395. {
  396.   short    *polypalette;
  397.   unsigned char    palette[768];
  398.   int i;
  399.   
  400.   /* Convert the palette to HDF format. */
  401.   for (polypalette = (short *) WIN_PALETTE(win)->display_palette, i = 0;
  402.        i < 768; i++, polypalette++)
  403.     palette[i] = (unsigned char) *polypalette;
  404.   
  405.   /* Write the palette out to the file. */
  406.   if (DFPputpal(outfile, (char *)palette, 0, "w") == 0)
  407.     return ST_OKAY;
  408.   else 
  409.     {
  410.       stprintf(state, "ERROR:  Problem writing palette to '%s'.\n", outfile);
  411.       return ST_ERROR;
  412.     }
  413. }
  414.  
  415.  
  416. int WriteRawPalette(state_t *state, window_t *win, char *outfile)
  417. {
  418.   int i;
  419.   char red[256], blue[256], green[256];   /* character arrays that */
  420.   /* contain palette rgb values */
  421.   FILE *fp;                /* palette file to be used */
  422.     
  423.   if ((fp = fopen(outfile, "w")) != NULL) 
  424.     {
  425.       /* Copy palette into arrays for writing. */
  426.       for (i = 0; i < 256; i++) 
  427.         {
  428.           red[i] = (char)WIN_PALETTE(win)->display_palette[i][R];
  429.           green[i] =(char)WIN_PALETTE(win)->display_palette[i][G];
  430.           blue[i] = (char)WIN_PALETTE(win)->display_palette[i][B];
  431.         }
  432.     
  433.       /* Write the raw palette to the file. */
  434.       fwrite(red,1,256,fp);
  435.       fwrite(green,1,256,fp);
  436.       fwrite(blue,1,256,fp);
  437.       fclose(fp);
  438.       
  439.       return ST_OKAY;
  440.     }
  441.   else 
  442.     {
  443.       stprintf(state, "ERROR:  Problem writing palette to '%s'.\n", outfile);
  444.       return ST_ERROR;
  445.     }
  446. }
  447.